<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
<style>
body {
  font-family: Helvetica, arial, sans-serif;
  font-size: 14px;
  line-height: 1.6;
  padding-top: 10px;
  padding-bottom: 10px;
  background-color: white;
  padding: 30px; }

body > *:first-child {
  margin-top: 0 !important; }
body > *:last-child {
  margin-bottom: 0 !important; }

a {
  color: #4183C4; }
a.absent {
  color: #cc0000; }
a.anchor {
  display: block;
  padding-left: 30px;
  margin-left: -30px;
  cursor: pointer;
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0; }

h1, h2, h3, h4, h5, h6 {
  margin: 20px 0 10px;
  padding: 0;
  font-weight: bold;
  -webkit-font-smoothing: antialiased;
  cursor: text;
  position: relative; }

h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor {
  background: url() no-repeat 10px center;
  text-decoration: none; }

h1 tt, h1 code {
  font-size: inherit; }

h2 tt, h2 code {
  font-size: inherit; }

h3 tt, h3 code {
  font-size: inherit; }

h4 tt, h4 code {
  font-size: inherit; }

h5 tt, h5 code {
  font-size: inherit; }

h6 tt, h6 code {
  font-size: inherit; }

h1 {
  font-size: 28px;
  color: black; }

h2 {
  font-size: 24px;
  border-bottom: 1px solid #cccccc;
  color: black; }

h3 {
  font-size: 18px; }

h4 {
  font-size: 16px; }

h5 {
  font-size: 14px; }

h6 {
  color: #777777;
  font-size: 14px; }

p, blockquote, ul, ol, dl, li, table, pre {
  margin: 15px 0; }

hr {
  background: transparent url() repeat-x 0 0;
  border: 0 none;
  color: #cccccc;
  height: 4px;
  padding: 0;
}

body > h2:first-child {
  margin-top: 0;
  padding-top: 0; }
body > h1:first-child {
  margin-top: 0;
  padding-top: 0; }
  body > h1:first-child + h2 {
    margin-top: 0;
    padding-top: 0; }
body > h3:first-child, body > h4:first-child, body > h5:first-child, body > h6:first-child {
  margin-top: 0;
  padding-top: 0; }

a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
  margin-top: 0;
  padding-top: 0; }

h1 p, h2 p, h3 p, h4 p, h5 p, h6 p {
  margin-top: 0; }

li p.first {
  display: inline-block; }
li {
  margin: 0; }
ul, ol {
  padding-left: 30px; }

ul :first-child, ol :first-child {
  margin-top: 0; }

dl {
  padding: 0; }
  dl dt {
    font-size: 14px;
    font-weight: bold;
    font-style: italic;
    padding: 0;
    margin: 15px 0 5px; }
    dl dt:first-child {
      padding: 0; }
    dl dt > :first-child {
      margin-top: 0; }
    dl dt > :last-child {
      margin-bottom: 0; }
  dl dd {
    margin: 0 0 15px;
    padding: 0 15px; }
    dl dd > :first-child {
      margin-top: 0; }
    dl dd > :last-child {
      margin-bottom: 0; }

blockquote {
  border-left: 4px solid #dddddd;
  padding: 0 15px;
  color: #777777; }
  blockquote > :first-child {
    margin-top: 0; }
  blockquote > :last-child {
    margin-bottom: 0; }

table {
  padding: 0;border-collapse: collapse; }
  table tr {
    border-top: 1px solid #cccccc;
    background-color: white;
    margin: 0;
    padding: 0; }
    table tr:nth-child(2n) {
      background-color: #f8f8f8; }
    table tr th {
      font-weight: bold;
      border: 1px solid #cccccc;
      margin: 0;
      padding: 6px 13px; }
    table tr td {
      border: 1px solid #cccccc;
      margin: 0;
      padding: 6px 13px; }
    table tr th :first-child, table tr td :first-child {
      margin-top: 0; }
    table tr th :last-child, table tr td :last-child {
      margin-bottom: 0; }

img {
  max-width: 100%; }

span.frame {
  display: block;
  overflow: hidden; }
  span.frame > span {
    border: 1px solid #dddddd;
    display: block;
    float: left;
    overflow: hidden;
    margin: 13px 0 0;
    padding: 7px;
    width: auto; }
  span.frame span img {
    display: block;
    float: left; }
  span.frame span span {
    clear: both;
    color: #333333;
    display: block;
    padding: 5px 0 0; }
span.align-center {
  display: block;
  overflow: hidden;
  clear: both; }
  span.align-center > span {
    display: block;
    overflow: hidden;
    margin: 13px auto 0;
    text-align: center; }
  span.align-center span img {
    margin: 0 auto;
    text-align: center; }
span.align-right {
  display: block;
  overflow: hidden;
  clear: both; }
  span.align-right > span {
    display: block;
    overflow: hidden;
    margin: 13px 0 0;
    text-align: right; }
  span.align-right span img {
    margin: 0;
    text-align: right; }
span.float-left {
  display: block;
  margin-right: 13px;
  overflow: hidden;
  float: left; }
  span.float-left span {
    margin: 13px 0 0; }
span.float-right {
  display: block;
  margin-left: 13px;
  overflow: hidden;
  float: right; }
  span.float-right > span {
    display: block;
    overflow: hidden;
    margin: 13px auto 0;
    text-align: right; }

code, tt {
  margin: 0 2px;
  padding: 0 5px;
  white-space: nowrap;
  border: 1px solid #eaeaea;
  background-color: #f8f8f8;
  border-radius: 3px; }

pre code {
  margin: 0;
  padding: 0;
  white-space: pre;
  border: none;
  background: transparent; }

.highlight pre {
  background-color: #f8f8f8;
  border: 1px solid #cccccc;
  font-size: 13px;
  line-height: 19px;
  overflow: auto;
  padding: 6px 10px;
  border-radius: 3px; }

pre {
  background-color: #f8f8f8;
  border: 1px solid #cccccc;
  font-size: 13px;
  line-height: 19px;
  overflow: auto;
  padding: 6px 10px;
  border-radius: 3px; }
  pre code, pre tt {
    background-color: transparent;
    border: none; }

sup {
    font-size: 0.83em;
    vertical-align: super;
    line-height: 0;
}
* {
	-webkit-print-color-adjust: exact;
}
@media screen and (min-width: 914px) {
    body {
        width: 854px;
        margin:0 auto;
    }
}
@media print {
	table, pre {
		page-break-inside: avoid;
	}
	pre {
		word-wrap: break-word;
	}
}
</style>
<title>队列</title>

</head>
<body>
<h1>队列</h1>

<ul>
<li><a href="#configuration">配置</a></li>
<li><a href="#basic-usage">基本用法</a></li>
<li><a href="#queueing-closures">队列闭包</a></li>
<li><a href="#running-the-queue-listener">运行队列监听器</a></li>
<li><a href="#push-queues">压入队列</a></li>
</ul>


<p><a name="configuration"></a></p>

<h2>配置</h2>

<p>Laravel 队列组件为不同的队列服务提供了统一的接口。队列允许您推迟处理一个耗时的任务，比如发送电子邮件，直到一个稍后的时间，这样可以加快应用程序请求的速度。</p>

<p>队列配置文件保存在 <code>app/config/queue.php</code>。在这个文件中您会发现框架中包含的每种队列驱动的连接配置，包括 <a href="http://kr.github.com/beanstalkd">Beanstalkd</a>, <a href="http://iron.io">IronMQ</a>, <a href="http://aws.amazon.com/sqs">Amazon SQS</a> 以及 synchronous (为本地应用) 驱动。</p>

<p>以下是列出的队列驱动所需的依赖：</p>

<ul>
<li>Beanstalkd: <code>pda/pheanstalk</code></li>
<li>Amazon SQS: <code>aws/aws-sdk-php</code></li>
<li>IronMQ: <code>iron-io/iron_mq</code></li>
</ul>


<p><a name="basic-usage"></a></p>

<h2>基本用法</h2>

<p>使用 <code>Queue::push</code> 函数把一个新任务压入队列：</p>

<p><strong>把一个新任务压入队列</strong></p>

<pre><code>Queue::push('SendEmail', array('message' =&gt; $message));
</code></pre>

<p>传递给 <code>push</code> 函数的第一个参数是用来处理这个任务的类的名字。第二个参数是需要传递给处理器的一个数组。一个任务处理器应该这样定义：</p>

<p><strong>定义一个任务处理器</strong></p>

<pre><code>class SendEmail {

    public function fire($job, $data)
    {
        //
    }

}
</code></pre>

<p>注意唯一必需的函数是 <code>fire</code>，它接受一个任务实例以及压入到队列时 <code>data</code> 的数组。</p>

<p>如果您想这个任务使用另一个名字而不是 <code>fire</code>，您可以指定在压入这个任务时指定：</p>

<p><strong>指定一个任务处理器函数</strong></p>

<pre><code>Queue::push('SendEmail@send', array('message' =&gt; $message));
</code></pre>

<p>一旦您处理了一个任务，它必须从队列中删除，这可以通过在任务实例上调用 <code>delete</code> 函数：</p>

<p><strong>删除一个已处理的任务</strong></p>

<pre><code>public function fire($job, $data)
{
    // Process the job...

    $job-&gt;delete();
}
</code></pre>

<p>如果您想从队列中遣返一个任务，可以使用 <code>release</code> 函数：</p>

<p><strong>从队列中遣返一个任务</strong></p>

<pre><code>public function fire($job, $data)
{
    // Process the job...

    $job-&gt;release();
}
</code></pre>

<p>您也可以指定任务被遣返前等待的秒数：</p>

<pre><code>$job-&gt;release(5);
</code></pre>

<p>如果在任务处理时发生了一个异常，将被自动遣返回队列。您可以使用 <code>attempts</code> 函数检查执行这个任务已经尝试的次数：</p>

<p><strong>检查已经尝试的次数</strong></p>

<pre><code>if ($job-&gt;attempts() &gt; 3)
{
    //
}
</code></pre>

<p>您也可以获取任务的标识符：</p>

<p><strong>获取任务标识</strong></p>

<pre><code>$job-&gt;getJobId();
</code></pre>

<p><a name="queueing-closures"></a></p>

<h2>队列闭包</h2>

<p>您也可以把一个闭包压入队列。这是一个非常方便的把快捷、简单的任务压入队列的方法：</p>

<p><strong>把一个闭包压入队列</strong></p>

<pre><code>Queue::push(function($job) use ($id)
{
    Account::delete($id);

    $job-&gt;delete();
});
</code></pre>

<blockquote><p><strong>注意:</strong> 当压入闭包到队列，<code>__DIR__</code> 以及 <code>__FILE__</code> 常量不应该被使用。</p></blockquote>

<p>当使用 Iron.io <a href="#push-queues">push queues</a>，您应该采取其他预防措施排队闭包。接收队列消息的后端应该检查一个令牌以验证这个请求来自 Iron.io。比如，您的压入队列后端应该像这样：<code>https://yourapp.com/queue/receive?token=SecretToken</code>。然后您可以在调度队列请求之前在应用程序中检查令牌的值。</p>

<p><a name="running-the-queue-listener"></a></p>

<h2>运行队列监听器</h2>

<p>Laravel 包含一个 Artisan 任务用于运行压入队列的新的任务。您可以通过使用 <code>queue:listen</code> 命令运行这个任务：</p>

<p><strong>开始队列监听</strong></p>

<pre><code>php artisan queue:listen
</code></pre>

<p>您可以指明监听器使用哪个队列连接：</p>

<pre><code>php artisan queue:listen connection
</code></pre>

<p>注意一旦这个任务开始，它将持续运行直到手动停止。您可以使用进程监控器比如 <a href="http://supervisord.org/">Supervisor</a> 来确认队列监听器没有停止运行。</p>

<p>您可以设置每个任务允许运行的时间（以秒为单位）：</p>

<p><strong>指定任务超时参数</strong></p>

<pre><code>php artisan queue:listen --timeout=60
</code></pre>

<p>可以使用 <code>queue:work</code> 函数只处理队列中的第一个任务：</p>

<p><strong>处理队列中的第一个任务</strong></p>

<pre><code>php artisan queue:work
</code></pre>

<p><a name="push-queues"></a></p>

<h2>压入队列</h2>

<p>压入队列允许您利用强大的 Laravel 4 队列功能而不需要运行任何守护进程或后台监听器。目前压入队列只支持 <a href="http://iron.io">Iron.io</a> 驱动。在开始之前，创建一个 Iron.io 帐号，并且添加 Iron 凭证到 <code>app/config/queue.php</code> 配置文件。</p>

<p>接下来，您可以使用 <code>queue:subscribe</code> Artisan 命令注册一个接收新的队列任务的 URL 后端：</p>

<p><strong>注册一个压入队列订阅者</strong></p>

<pre><code>php artisan queue:subscribe queue_name http://foo.com/queue/receive
</code></pre>

<p>现在，当您登录到 Iron 控制面板，您将看到新的压入队列，以及订阅的 URL。您可以按照您的意愿订阅尽可能多的 URLs到指定的队列。接下来，为 <code>queue/receive</code> 后端创建一个路由并且从 <code>Queue::marshal</code> 函数返回相应：</p>

<pre><code>Route::post('queue/receive', function()
{
    return Queue::marshal();
});
</code></pre>

<p><code>marshal</code> 函数将用于触发正确的任务处理器类。为了在压入队列中触发任务，和常规的队列一样使用相同的 <code>Queue::push</code> 函数。</p>
</body>
</html>